﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace LogAnalytics.Edit
{
    public partial class Analytics : QT.Windows.Shell.GlassForm
    {
        #region Attributes

        private string QQWryPath = Application.StartupPath + @"\QQWry.Dat"; 
        private string LogPath = Environment.CurrentDirectory + @"\logs";
        private int perLineStep = 7;    //每个线路的分析步骤数
        private int perSiteStep = 2;    //每个站点除perLineStep外还需要的步骤数

        private AnalyResult myResult = new AnalyResult();

        private Thread myThread = null;
        private delegate ListView.ListViewItemCollection myDeleGategetItems();
        private delegate TimeRange myDeleGategetTimeRange();
        private delegate void myDeleGatesetMsg(int index, string s);
        private delegate void myDeleGateoutMsgInRichTextBox(string s);

        #endregion

        #region Form

        public Analytics()
        {
            InitializeComponent();
        }

        protected override void OnShown(EventArgs e)
        {
            base.OnShown(e);
            this.lblStep1.ForeColor = Color.Red;
            this.gbtnPrevious.Visible = false;
            this.Tag = "1";
            loadStep1();
            this.pStep1.BringToFront();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            this.statusStrip1.BackColor = AeroColor;
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            this.pSite.Location = new Point((this.ClientSize.Width - this.pSite.Width) / 2, (this.ClientSize.Height - this.pSite.Height) / 2);
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);
            e.Cancel = true;

            if (myThread != null && myThread.IsAlive)
            {
                if (MessageBox.Show("正在进行日志分析，确认要强制退出吗？","系统提示",MessageBoxButtons.YesNo,MessageBoxIcon.Question) == DialogResult.No) return;
                myThread.Abort();
            }

            e.Cancel = false;
        }

        #endregion

        #region Event(GlassButton)

        private void gbtnPrevious_Click(object sender, EventArgs e)
        {
            if (this.Tag == null)
            {
                MessageBox.Show("内部错误：Tag为NULL");
                return;
            }

            switch (this.Tag.ToString())
            {
                case "2":
                    this.lblStep2.ForeColor = Color.Gray;
                    this.lblStep1.ForeColor = Color.Red;
                    this.gbtnPrevious.Visible = false;
                    this.Tag = "1";
                    this.pStep1.BringToFront();
                    break;
                default:
                    break;
            }
        }

        private void gbtnNext_Click(object sender, EventArgs e)
        {
            if (this.Tag == null)
            {
                MessageBox.Show("内部错误：Tag为NULL");
                return;
            }

            switch (this.Tag.ToString())
            {
                case "1":
                    if (this.lvSiteList.Items.Count == 0)
                    {
                        MessageBox.Show("您还没有添加任务");
                        return;
                    }
                    this.lblStep1.ForeColor = Color.Gray;
                    this.lblStep2.ForeColor = Color.Red;
                    this.gbtnPrevious.Visible = true;
                    this.Tag = "2";
                    if (this.pStep2.Tag == null) loadStep2();
                    this.pStep2.BringToFront();
                    break;
                case "2":
                    saveSetting();
                    this.lblStep2.ForeColor = Color.Gray;
                    this.lblStep3.ForeColor = Color.Red;
                    this.gbtnPrevious.Visible = false;
                    this.gbtnNext.Visible = false;
                    this.Tag = "3";
                    if (this.pStep3.Tag == null) loadStep3();
                    this.pStep3.BringToFront();
                    break;
                case "3":
                    this.lblStep3.ForeColor = Color.Gray;
                    this.lblStep4.ForeColor = Color.Red;
                    this.gbtnNext.Text = "完成";
                    this.gbtnNext.Visible = true;
                    this.Tag = "4";
                    loadStep4();
                    this.pStep4.BringToFront();
                    break;
                case "4":
                    this.Close();
                    break;
                default:
                    break;
            }
        }

        #endregion

        #region Step1

        private void loadStep1()
        {
            DataTable dt = LogBase.SiteManage.getUsing();
            foreach (DataRow dr in dt.Rows)
            {
                ListViewItem item = new ListViewItem();
                item.Text = (this.lvSiteList.Items.Count + 1).ToString();
                item.SubItems.Add(dr["SiteName"].ToString());
                item.SubItems.Add(dr["TelDirectory"].ToString());
                item.SubItems.Add(dr["UniDirectory"].ToString());
                item.SubItems.Add(dr["Guid"].ToString());
                if (this.lvSiteList.Items.Count % 2 == 1) item.BackColor = Color.Gainsboro;

                this.lvSiteList.Items.Add(item);
            }

            dt.Dispose();
            this.tsslMsg.Text = string.Format("共{0}条任务", this.lvSiteList.Items.Count);

            this.pStep1.Tag = "1";
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            List<string> guids = new List<string>();
            foreach (ListViewItem item in this.lvSiteList.Items)
            {
                guids.Add(item.SubItems[4].Text);
            }

            DataTable dt = LogBase.SiteManage.getUsing();
            this.lvList.Items.Clear();
            foreach (DataRow dr in dt.Rows)
            {
                if (guids.Contains(dr["guid"].ToString())) continue;

                ListViewItem item = new ListViewItem();
                item.Text = (this.lvList.Items.Count+1).ToString();
                item.SubItems.Add(dr["SiteName"].ToString());
                item.SubItems.Add(dr["TelDirectory"].ToString());
                item.SubItems.Add(dr["UniDirectory"].ToString());
                item.SubItems.Add(dr["Guid"].ToString());

                this.lvList.Items.Add(item);
            }

            dt.Dispose();
            this.pFunc.Enabled = false;
            this.pStep1.Enabled = false;
            this.pSite.Visible = true;
            this.pSite.BringToFront();
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in this.lvSiteList.SelectedItems)
            {
                this.lvSiteList.Items.Remove(item);
            }

            foreach (ListViewItem item in this.lvSiteList.Items)
            {
                item.Text = (item.Index + 1).ToString();
            }

            this.tsslMsg.Text = string.Format("共{0}条任务", this.lvSiteList.Items.Count);
        }

        private void gbtnOK_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in this.lvList.SelectedItems)
            {
                ListViewItem newItem = (ListViewItem)item.Clone();
                newItem.Text = (this.lvSiteList.Items.Count + 1).ToString();
                if (this.lvSiteList.Items.Count % 2 == 1) newItem.BackColor = Color.Gainsboro;

                this.lvSiteList.Items.Add(newItem);
            }

            this.tsslMsg.Text = string.Format("共{0}条任务", this.lvSiteList.Items.Count);
            gbtnClose_Click(sender, e);
        }

        private void gbtnClose_Click(object sender, EventArgs e)
        {
            this.pFunc.Enabled = true;
            this.pStep1.Enabled = true;
            this.pSite.Visible = false;
        }

        #endregion

        #region Step2

        private void loadStep2()
        {
            try
            {
                DateTime myDate = DateTime.Now.AddDays(-1);
                this.dtpStart.Value = myDate;
                this.dtpEnd.Value = myDate;

                ConfigurationManager.RefreshSection("appSettings");

                string filtertype = ConfigurationManager.AppSettings["filtertype"];
                if (filtertype == "0") this.rbtnInclude.Checked = true;
                else this.rbtnExclude.Checked = true;
                string filters = ConfigurationManager.AppSettings["filter"];
                this.tbFilter.Text = filters;

                string QQWry = ConfigurationManager.AppSettings["QQWryPath"];
                string IPUpdateType = ConfigurationManager.AppSettings["IPUpdateType"];
                string IPTop = ConfigurationManager.AppSettings["IPTop"];
                if (!string.IsNullOrEmpty(QQWry)) QQWryPath = QQWry;
                this.tbQQWryPath.Text = QQWryPath;
                switch (IPUpdateType)
                {
                    case "1":
                        this.rbtnAllIP.Checked = true;
                        break;
                    case "2":
                        this.rbtnMultiIP.Checked = true;
                        break;
                    case "3":
                        this.rbtnNoIP.Checked = true;
                        break;
                    default:
                        break;
                }
                this.nudTopIP.Value = decimal.Parse(IPTop);

                this.pStep2.Tag = "1";
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void saveSetting()
        {
            try
            {
                Configuration appConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                appConfig.AppSettings.Settings["filtertype"].Value = this.rbtnInclude.Checked ? "0" : "1";
                appConfig.AppSettings.Settings["filter"].Value = this.tbFilter.Text;
                appConfig.AppSettings.Settings["QQWryPath"].Value = this.tbQQWryPath.Text;
                if (this.rbtnAllIP.Checked) appConfig.AppSettings.Settings["IPUpdateType"].Value = "1";
                if (this.rbtnMultiIP.Checked)
                {
                    appConfig.AppSettings.Settings["IPUpdateType"].Value = "2";
                    appConfig.AppSettings.Settings["IPTop"].Value = this.nudTopIP.Value.ToString();
                }
                if (this.rbtnNoIP.Checked) appConfig.AppSettings.Settings["IPUpdateType"].Value = "3";
                appConfig.Save();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void rbtnMulti_CheckedChanged(object sender, EventArgs e)
        {
            if (this.rbtnMulti.Checked)
            {
                this.lblLine.Visible = true;
                this.dtpEnd.Visible = true;
            }
            else
            {
                this.lblLine.Visible = false;
                this.dtpEnd.Visible = false;
            }
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            OpenFileDialog myOpenFileDialog = new OpenFileDialog();
            myOpenFileDialog.ValidateNames = true;
            myOpenFileDialog.Multiselect = false;
            myOpenFileDialog.Filter = "纯真IP数据库QQWry.dat|*.dat";
            myOpenFileDialog.FilterIndex = 1;
            myOpenFileDialog.FileName = "QQWry.dat";
            myOpenFileDialog.AddExtension = true;
            if (myOpenFileDialog.ShowDialog() == DialogResult.Cancel)
            {
                return;
            }
            this.tbQQWryPath.Text = myOpenFileDialog.FileName;
        }

        private void rbtnMultiIP_CheckedChanged(object sender, EventArgs e)
        {
            if (this.rbtnMultiIP.Checked) this.nudTopIP.Enabled = true;
            else this.nudTopIP.Enabled = false;
        }

        #endregion

        #region Step3

        private void loadStep3()
        {
            this.pbProgress.Maximum = this.lvSiteList.Items.Count * (perLineStep * 2 + perSiteStep) * (dtpEnd.Value.Subtract(dtpStart.Value).Days + 1) + 1;    
            myThread = new Thread(new ThreadStart(myThreadAnalytics));
            myThread.Start();
        }

        private void btnLogs_Click(object sender, EventArgs e)
        {
            if (this.rtbLogs.Visible == true) this.rtbLogs.Visible = false;
            else this.rtbLogs.Visible = true;
        }

        private void myThreadAnalytics()
        {
            try
            {
                string logs = ConfigurationManager.AppSettings["logs"];
                if (logs != "") LogPath = logs;
                if (!Directory.Exists(LogPath)) Directory.CreateDirectory(LogPath);

                outMsgInRichTextBox(string.Format("[{0}] 启动日志分析\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
                System.Diagnostics.Stopwatch Stepwatch = System.Diagnostics.Stopwatch.StartNew();
                System.Diagnostics.Stopwatch Totalwatch = System.Diagnostics.Stopwatch.StartNew();

                #region Initialization

                setMsg(0, "初始化配置……");

                ConfigurationManager.RefreshSection("appSettings");
                string server = ConfigurationManager.AppSettings["Server"];
                string database = ConfigurationManager.AppSettings["DataBase"];
                string uid = ConfigurationManager.AppSettings["UserID"];
                string pass = ConfigurationManager.AppSettings["Password"];
                string pageexclude = ConfigurationManager.AppSettings["pageexclude"];
                string filtertype = this.rbtnInclude.Checked ? "" : " not ";
                List<string> filters = new List<string>(this.tbFilter.Text.Split(','));
                string IPUpdateType = ConfigurationManager.AppSettings["IPUpdateType"];
                string IPTop = ConfigurationManager.AppSettings["IPTop"];
                string SaveType = ConfigurationManager.AppSettings["SaveType"];
                int SaveValue = int.Parse(ConfigurationManager.AppSettings["SaveValue"]);
                LogBase.LogParserApi LogAnaly = null;
                TimeRange myTime = getTimeRange();
                DataTable dt = null;
                myResult.Success = myResult.Fail = myResult.Skip = 0;
                myResult.SuccessSiteName = new List<string>(); 
                myResult.FailSiteName = new List<string>();
                myResult.SkipSiteName = new List<string>();

                outMsgInRichTextBox(string.Format("[{0}] 初始化配置完成，耗时：{1}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), Stepwatch.Elapsed));
                Stepwatch.Reset();

                #endregion

                #region Analytics
                                
                int step = 1;    //日志分析的当前步骤

                LogBase.Log.ClearTable();

                foreach (ListViewItem item in getItems())
                {
                    outMsgInRichTextBox(string.Format("[{0}] 开始处理站点{1}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), item.SubItems[1].Text));

                    for (DateTime LogDate = myTime.Start; LogDate.Date <= myTime.End.Date; LogDate = LogDate.AddDays(1))
                    {
                        LogBase.Log.ClearMainTable();

                        #region CheckExsit

                        if (LogBase.Log.CheckAnaly(item.SubItems[4].Text.Trim(), LogDate.ToString("yyyy-MM-dd")))
                        {
                            outMsgInRichTextBox(string.Format("[{0}] 跳过站点{1}（原因：日志已分析）\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), item.SubItems[1].Text));
                            myResult.Skip++;
                            myResult.SkipSiteName.Add(item.SubItems[1].Text + "(" + LogDate.ToString("yyyy-MM-dd") + ")");
                            step += perLineStep * 2 + perSiteStep;
                            continue;
                        }
                        Stepwatch.Start();

                        #endregion

                        try
                        {
                            for (int ServerType = 0; ServerType < 2; ServerType++) //0代表联通，1代表电信
                            {
                                #region Analy

                                setMsg(step, string.Format("站点{0}{1}日志分析({2})", item.SubItems[1].Text, ServerType == 1 ? "电信" : "联通", LogDate.ToString("yyyy-MM-dd")));

                                if (string.IsNullOrEmpty(item.SubItems[ServerType == 1 ? 2 : 3].Text))
                                {
                                    step += perLineStep;
                                    continue;
                                }

                                try
                                {
                                    LogAnaly = new LogBase.LogParserApi();
                                    LogAnaly.InitSQLServer(server, database, QT.Security.AESHelper.AESDecrypt(uid), QT.Security.AESHelper.AESDecrypt(pass));
                                    LogAnaly.Execute(string.Format(item.SubItems[ServerType == 1 ? 2 : 3].Text, @"*" + LogDate.ToString("yyMMdd") + ".log"), filtertype, filters, item.SubItems[4].Text, LogDate.ToString("yyyy-MM-dd"), ServerType.ToString());
                                }
                                catch (System.Runtime.InteropServices.COMException)
                                {
                                    if (MessageBox.Show("检测到您电脑上未安装 Log Parser 2.2，要现在安装吗？", "系统提示", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes) setupLogParser();
                                    return;
                                }

                                outMsgInRichTextBox(string.Format("[{0}] 站点{1}{2}日志({3})分析完成，耗时：{4}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), item.SubItems[1].Text, ServerType == 1 ? "电信" : "联通", LogDate.ToString("yyyy-MM-dd"), Stepwatch.Elapsed));
                                Stepwatch.Reset();
                                Stepwatch.Start();
                                step++;

                                #endregion

                                #region Clear

                                if (pageexclude == "1")
                                {
                                    setMsg(step, string.Format("站点{0}{1}数据清理({2})", item.SubItems[1].Text, ServerType == 1 ? "电信" : "联通", LogDate.ToString("yyyy-MM-dd")));

                                    LogBase.Log.ClearRecord(item.SubItems[4].Text.Trim());

                                    outMsgInRichTextBox(string.Format("[{0}] 站点{1}{2}数据({3})清理完成，耗时：{4}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), item.SubItems[1].Text, ServerType == 1 ? "电信" : "联通", LogDate.ToString("yyyy-MM-dd"), Stepwatch.Elapsed));
                                }

                                Stepwatch.Reset();
                                Stepwatch.Start();
                                step++;

                                #endregion

                                #region UpdateIPAddress

                                if (IPUpdateType == "1" || IPUpdateType == "2")
                                {
                                    setMsg(step, string.Format("填充站点{0}{1}IP地址信息({2})", item.SubItems[1].Text, ServerType == 1 ? "电信" : "联通", LogDate.ToString("yyyy-MM-dd")));

                                    dt = LogBase.Log.getIPList(int.Parse(IPUpdateType == "2" ? IPTop : "0"));
                                    LogBase.QQWryHelper QQWry = new LogBase.QQWryHelper(QQWryPath);
                                    LogBase.IPLocation loc = new LogBase.IPLocation();
                                    Int64 num = 0;
                                    Int64 count = dt.Rows.Count;
                                    foreach (DataRow dr in dt.Rows)
                                    {
                                        loc = QQWry.GetIPLocation(dr[0].ToString());
                                        LogBase.Log.UpdateIPAddress(loc);
                                        num++;
                                        setMsg(step, string.Format("填充站点{0}{1}IP地址信息({2})……,已填充：{3}/{4}", item.SubItems[1].Text, ServerType == 1 ? "电信" : "联通", LogDate.ToString("yyyy-MM-dd"), num, count));
                                    }
                                    dt.Dispose();

                                    outMsgInRichTextBox(string.Format("[{0}] 站点{1}{2}填充IP地址({3})信息完成，耗时：{4}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), item.SubItems[1].Text, ServerType == 1 ? "电信" : "联通", LogDate.ToString("yyyy-MM-dd"), Stepwatch.Elapsed));
                                }
                                Stepwatch.Reset();
                                Stepwatch.Start();
                                step++;

                                #endregion

                                #region SeparateResult

                                #region AnalybyIP

                                setMsg(step, string.Format("分离站点{0}{1}按IP访问统计结果({2})", item.SubItems[1].Text, ServerType == 1 ? "电信" : "联通", LogDate.ToString("yyyy-MM-dd")));

                                LogBase.Log.AddRecordbyIP();

                                outMsgInRichTextBox(string.Format("[{0}] 站点{1}{2}分离按IP访问统计结果({3})完成，耗时：{4}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), item.SubItems[1].Text, ServerType == 1 ? "电信" : "联通", LogDate.ToString("yyyy-MM-dd"), Stepwatch.Elapsed));
                                Stepwatch.Reset();
                                Stepwatch.Start();
                                step++;

                                #endregion

                                #region AnalybyPage

                                setMsg(step, string.Format("分离站点{0}{1}按页面访问统计结果({2})", item.SubItems[1].Text, ServerType == 1 ? "电信" : "联通", LogDate.ToString("yyyy-MM-dd")));

                                LogBase.Log.AddRecordbyPage();

                                outMsgInRichTextBox(string.Format("[{0}] 站点{1}{2}分离按页面访问统计结果({3})完成，耗时：{4}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), item.SubItems[1].Text, ServerType == 1 ? "电信" : "联通", LogDate.ToString("yyyy-MM-dd"), Stepwatch.Elapsed));
                                Stepwatch.Reset();
                                Stepwatch.Start();
                                step++;

                                #endregion

                                #region AnalybyGeneral

                                setMsg(step, string.Format("站点{0}{1}IIS日志概要临时数据统计({2})", item.SubItems[1].Text, ServerType == 1 ? "电信" : "联通", LogDate.ToString("yyyy-MM-dd")));

                                LogBase.Log.AddRecordGeneral();

                                outMsgInRichTextBox(string.Format("[{0}] 站点{1}{2}IIS日志概要临时数据统计({3})完成，耗时：{4}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), item.SubItems[1].Text, ServerType == 1 ? "电信" : "联通", LogDate.ToString("yyyy-MM-dd"), Stepwatch.Elapsed));
                                Stepwatch.Reset();
                                Stepwatch.Start();
                                step++;

                                #endregion

                                #region ClearMainTable

                                setMsg(step, string.Format("站点{0}{1}IIS日志分析临时表删除({2})", item.SubItems[1].Text, ServerType == 1 ? "电信" : "联通", LogDate.ToString("yyyy-MM-dd")));

                                LogBase.Log.ClearMainTable();

                                outMsgInRichTextBox(string.Format("[{0}] 站点{1}{2}IIS日志分析临时表({3})清理完成，耗时：{4}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), item.SubItems[1].Text, ServerType == 1 ? "电信" : "联通", LogDate.ToString("yyyy-MM-dd"), Stepwatch.Elapsed));
                                Stepwatch.Reset();
                                Stepwatch.Start();
                                step++;

                                #endregion

                                #endregion
                            }

                            #region ImportResult

                            setMsg(step, string.Format("站点{0}日志分析结果导入正式表({1})", item.SubItems[1].Text, LogDate.ToString("yyyy-MM-dd")));

                            try
                            {
                                LogBase.Log.ImportResult(item.SubItems[4].Text.Trim(), LogDate.ToString("yyyy-MM-dd"), SaveType, SaveValue);
                            }
                            catch (Exception ex)
                            {
                                try
                                {
                                    LogBase.DataManage.DeleteRecord(item.SubItems[4].Text, LogDate.ToString("yyyy-MM-dd"));
                                }
                                catch (Exception e)
                                {
                                    MessageBox.Show(string.Format("站点：{0}，日期：{1}数据库清理失败，请手工进行清理。\n错误信息：{2}", item.SubItems[1].Text, LogDate.ToString("yyyy-MM-dd"), e.Message));
                                    myResult.Fail++;
                                    myResult.FailSiteName.Add(item.SubItems[1].Text + "(" + LogDate.ToString("yyyy-MM-dd") + ")");
                                    showErr(ex.Message);
                                    gbtnNext_Click(new object(), new EventArgs());
                                    return;
                                }

                                throw new Exception(ex.Message);
                            }

                            outMsgInRichTextBox(string.Format("[{0}] 站点{1}日志分析结果导入正式表({2})完成，耗时：{3}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), item.SubItems[1].Text, LogDate.ToString("yyyy-MM-dd"), Stepwatch.Elapsed));
                            Stepwatch.Reset();
                            Stepwatch.Start();
                            step++;

                            #endregion

                            #region ClearRecord

                            setMsg(step, string.Format("清理站点{0}IIS日志分析临时数据({1})", item.SubItems[1].Text, LogDate.ToString("yyyy-MM-dd")));

                            LogBase.Log.ClearTable();

                            outMsgInRichTextBox(string.Format("[{0}] 清理IIS日志概要临时数据完成，耗时：{1}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), Stepwatch.Elapsed));
                            Stepwatch.Reset();
                            Stepwatch.Start();
                            step++;

                            #endregion

                        }
                        catch (Exception ex)
                        {
                            outMsgInRichTextBox(string.Format("[{0}] 跳过站点{1}（原因：{2}）\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), item.SubItems[1].Text, ex.Message));
                            myResult.Fail++;
                            myResult.FailSiteName.Add(item.SubItems[1].Text + "(" + LogDate.ToString("yyyy-MM-dd") + ")");
                            step = item.Index * (perLineStep * 2 + perSiteStep) * (myTime.End.Subtract(myTime.Start).Days + 1) + (perLineStep * 2 + perSiteStep) * (LogDate.Subtract(myTime.Start).Days + 1) + 1;
                            showErr(ex.Message);
                            continue;
                        }

                        myResult.Success++;
                        myResult.SuccessSiteName.Add(item.SubItems[1].Text + "(" + LogDate.ToString("yyyy-MM-dd") + ")");
                    }
                }

                setMsg(step, string.Format("日志分析完成，总计耗时：{0}", Totalwatch.Elapsed));
                outMsgInRichTextBox(string.Format("[{0}] 日志分析完成，总耗时：{1}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), Totalwatch.Elapsed));
                Totalwatch.Stop();
                MessageBox.Show("日志分析完成");

                gbtnNext_Click(new object(), new EventArgs());

                #endregion
            }
            catch (ThreadAbortException)
            {
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private ListView.ListViewItemCollection getItems()
        {
            if (this.InvokeRequired)
            {
                return this.Invoke(new myDeleGategetItems(getItems)) as ListView.ListViewItemCollection;
            }
            else
            {
                return this.lvSiteList.Items;
            }
        }

        private TimeRange getTimeRange()
        {
            if (this.InvokeRequired)
            {
                return (TimeRange)this.Invoke(new myDeleGategetTimeRange(getTimeRange));
            }
            else
            {
                TimeRange myTime = new TimeRange();
                myTime.Start = this.dtpStart.Value;
                myTime.End = this.rbtnSingle.Checked ? this.dtpStart.Value : this.dtpEnd.Value;
                return myTime;
            }
        }

        private void setMsg(int index, string s)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new myDeleGatesetMsg(setMsg), new object[] { index, s });
            }
            else
            {
                this.pbProgress.Value = index;
                this.lblProgress.Text = s;
            }
        }

        private void outMsgInRichTextBox(string s)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new myDeleGateoutMsgInRichTextBox(outMsgInRichTextBox), new object[] { s });
            }
            else
            {
                try
                {
                    this.rtbLogs.AppendText(s);
                    FileStream fs = new FileStream(LogPath + @"\Analy" + DateTime.Now.ToString("yyyy-MM-dd") + @".log", FileMode.Append, FileAccess.Write, FileShare.Read);
                    StreamWriter text = new StreamWriter(fs);
                    text.WriteLine(s);
                    text.Flush();
                    fs.Close();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        private void showErr(string s)
        {
            try
            {
                FileStream fs = new FileStream(LogPath + @"\Error" + DateTime.Now.ToString("yyyy-MM") + @".log", FileMode.Append, FileAccess.Write, FileShare.Read);
                StreamWriter text = new StreamWriter(fs);
                text.WriteLine(string.Format("[{0}] {1}\n", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), s));
                text.Flush();
                fs.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void setupLogParser()
        {
            string LogParserFile = @".\LogParser.msi";
            if (!File.Exists(LogParserFile))
            {
                byte[] buffer = Properties.Resources.LogParser;//这个是添加EXE到程序资源时的名称
                FileStream FS = new FileStream(LogParserFile, FileMode.Create);//新建文件
                BinaryWriter BWriter = new BinaryWriter(FS);//以二进制打开文件流
                BWriter.Write(buffer, 0, buffer.Length);//从资源文件读取文件内容，写入到一个文件中
                BWriter.Close();
                FS.Close();
            }

            Process.Start(LogParserFile);
        }

        #endregion

        #region Step4

        private void loadStep4()
        {
            this.lblCount.Text = string.Format("分析站点总数：{0}", this.lvSiteList.Items.Count);
            this.pbCount.Location = new Point(this.lblCount.Location.X + this.lblCount.Width + 20, this.pbCount.Location.Y);
            this.lblSuccess.Text = string.Format("成功：{0}", myResult.Success.ToString());
            this.pbSuccess.Location = new Point(this.lblSuccess.Location.X + this.lblSuccess.Width + 20, this.pbSuccess.Location.Y);
            this.lblFail.Text = string.Format("失败：{0}", myResult.Fail.ToString());
            this.pbFail.Location = new Point(this.lblFail.Location.X + this.lblFail.Width + 20, this.pbFail.Location.Y);
            if (myResult.Fail > 0) this.lblFail.ForeColor = Color.Red;
            this.lblSkip.Text = string.Format("跳过：{0}", myResult.Skip.ToString());
            this.pbSkip.Location = new Point(this.lblSkip.Location.X + this.lblSkip.Width + 20, this.pbSkip.Location.Y);
        }

        private void pbCount_Click(object sender, EventArgs e)
        {
            List<string> SiteName = new List<string>();
            foreach (ListViewItem item in this.lvSiteList.Items)
            {
                SiteName.Add(item.SubItems[1].Text);
            }

            Shower myShow = new Shower(null, string.Join("\n", SiteName.ToArray()));
            myShow.ShowDialog();
            myShow.Dispose();
        }

        private void pbSuccess_Click(object sender, EventArgs e)
        {
            Shower myShow = new Shower(null, string.Join("\n",myResult.SuccessSiteName.ToArray()));
            myShow.ShowDialog();
            myShow.Dispose();
        }

        private void pbFail_Click(object sender, EventArgs e)
        {
            Shower myShow = new Shower(null, string.Join("\n",myResult.FailSiteName.ToArray()));
            myShow.ShowDialog();
            myShow.Dispose();
        }

        private void pbSkip_Click(object sender, EventArgs e)
        {
            Shower myShow = new Shower(null, string.Join("\n",myResult.SkipSiteName.ToArray()));
            myShow.ShowDialog();
            myShow.Dispose();
        }

        private void llblLogs_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            Process.Start("explorer.exe", LogPath);
        }

        #endregion
    }

    /// <summary>
    /// 日志分析的时间区间
    /// </summary>
    public struct TimeRange
    {
        /// <summary>
        /// 开始时间
        /// </summary>
        public DateTime Start;
        /// <summary>
        /// 结束时间
        /// </summary>
        public DateTime End;
    }

    /// <summary>
    /// 日志分析结果
    /// </summary>
    public struct AnalyResult
    {
        /// <summary>
        /// 成功数量
        /// </summary>
        public int Success;
        /// <summary>
        /// 成功的站点名称
        /// </summary>
        public List<string> SuccessSiteName;
        /// <summary>
        /// 失败数量
        /// </summary>
        public int Fail;
        /// <summary>
        /// 失败的站点名称
        /// </summary>
        public List<string> FailSiteName;
        /// <summary>
        /// 跳过数量
        /// </summary>
        public int Skip;
        /// <summary>
        /// 跳过的站点名称
        /// </summary>
        public List<string> SkipSiteName;
    }
}
